package zhyioo.testframe;

import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener, RecyclerViewAdapter.OnItemClickLitener {

    protected int TextLogger = Color.rgb(0x80, 0x80, 0x80);
    protected int TextNote = Color.rgb(0x59, 0x59, 0x59);
    protected int TextMessage = Color.rgb(0x7E, 0xC2, 0xFF);
    protected int TextTips = Color.rgb(0xFF, 0x80, 0xC0);
    protected int TextInfo = Color.rgb(0x00, 0x82, 0xFF);
    protected int TextResult = Color.rgb(0x00, 0x00, 0xFF);
    protected int TextWarning = Color.rgb(0xD7, 0xAB, 0x69);
    protected int TextHighWarning = Color.rgb(0xBD, 0x63, 0xC5);
    protected int TextError = Color.rgb(0xFF, 0x00, 0x00);

    private TextView tv_log = null;
    private Button btn_clean = null;
    private Button btn_shot = null;
    private ScrollView sv_log = null;
    private ListView lv_test = null;
    private Class<?> mClassModule = null;
    private String[] tests = null;
    private Object mObject = null;
    private RecyclerView rv_test = null;
    private RecyclerViewAdapter rv_adapter = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            mClassModule = Class.forName(MainActivity.class.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        mObject = this;
        tv_log = (TextView) findViewById(R.id.tv_log);
        btn_clean = (Button) findViewById(R.id.btn_clean);
        btn_shot = (Button) findViewById(R.id.btn_shot);
        sv_log = (ScrollView) findViewById(R.id.sv_log);
        lv_test = (ListView) findViewById(R.id.lv_test);

        btn_clean.setOnClickListener(this);
        btn_shot.setOnClickListener(this);
        lv_test.setOnItemClickListener(this);

        String[] itemArray = getResources().getStringArray(R.array.Tests);
        String[] titleArray = new String[itemArray.length];
        tests = new String[itemArray.length];
        for(int i = 0;i < itemArray.length; ++i) {
            if(itemArray[i].contains("|")) {
                int index = itemArray[i].indexOf('|');
                titleArray[i] = itemArray[i].substring(index + 1);
                tests[i] = itemArray[i].substring(0, index);
            } else {
                titleArray[i] = itemArray[i];
                tests[i] = itemArray[i];
            }
        }
        lv_test.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, titleArray));

        rv_test = (RecyclerView) findViewById(R.id.rv_test);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        rv_test.setLayoutManager(linearLayoutManager);
        rv_adapter = new RecyclerViewAdapter(this, Arrays.asList(titleArray));
        rv_test.setAdapter(rv_adapter);
        rv_test.setHasFixedSize(true);
        rv_adapter.setOnItemClickLitener(this);
        rv_test.setItemAnimator(new DefaultItemAnimator());
        rv_test.addItemDecoration(new DividerItemDecoration(this,
                DividerItemDecoration.VERTICAL_LIST));

        verifyStoragePermissions();

        OnInit();
    }

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE" };

    public void verifyStoragePermissions() {

        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限，去申请写的权限，会弹出对话框
                ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void OnInit() {

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_clean:
                tv_log.setText("");
                break;
            case R.id.btn_shot:
                Shot(v);
                break;
            default:
                break;
        }
    }

    private void Shot(View v) {
        View rootView = v.getRootView();
        rootView.setDrawingCacheEnabled(true);
        rootView.buildDrawingCache();
        Bitmap bitmap = rootView.getDrawingCache();
        if(bitmap != null) {
            FileOutputStream outStream;
            try {
                SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddhh");
                String date = sDateFormat.format(new java.util.Date());
                String fileName = "/sdcard/testframe/view_screenshot_";
                fileName += date;
                fileName += ".png";

                File file = new File(fileName);
                outStream = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
                outStream.flush();
                outStream.close();

                _appendText("Save To:" + fileName);
            } catch (Exception e) {
                _appendText(e);
            }
        }
    }

    protected SpannableStringBuilder _getColorText(int color, String text) {
        SpannableStringBuilder style = new SpannableStringBuilder(text);
        style.setSpan(new ForegroundColorSpan(color), 0, text.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        return style;
    }

    protected void _appendText(final String msg, final int color) {
        tv_log.post(new Runnable() {
            @Override
            public void run() {
                tv_log.append(_getColorText(color, msg + "\n"));
                sv_log.fullScroll(ScrollView.FOCUS_DOWN);
            }
        });
    }

    protected void _appendText(final String msg) {
        _appendText(msg, TextNote);
    }

    protected void _appendText(final Throwable e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        String errMsg = sw.toString();

        _appendText(errMsg, TextError);
    }

    protected SpannableStringBuilder _getBitmapText(String path) {
        Bitmap b = BitmapFactory.decodeFile(path);
        ImageSpan imgSpan = new ImageSpan(this, b);
        SpannableStringBuilder spanString = new SpannableStringBuilder("icon");
        spanString.setSpan(imgSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spanString;
    }

    protected void _appendImage(final String path){
        tv_log.post(new Runnable() {
            @Override
            public void run() {
                tv_log.append(_getBitmapText(path));
                tv_log.append("\n");
                sv_log.fullScroll(ScrollView.FOCUS_DOWN);
            }
        });
    }

    protected void onItemClick(final int position) {
        long currentTimeMillis = System.currentTimeMillis();
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(currentTimeMillis);
        String sTime = String.format("%02d:%02d:%02d.%03d ", calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND));

        tv_log.append(_getColorText(TextTips, sTime));
        tv_log.append(_getColorText(TextLogger, "Call:<"));
        tv_log.append(_getColorText(TextInfo, tests[position]));
        tv_log.append(_getColorText(TextLogger, ">\n"));

        Thread workThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    long currentTimeMillis = System.currentTimeMillis();
                    Method method = null;
                    method = mClassModule.getMethod(tests[position]);
                    method.invoke(mObject);

                    long workTimeMs = System.currentTimeMillis() - currentTimeMillis;
                    String sMsg = "耗时:<";
                    sMsg += workTimeMs;
                    sMsg += "ms>";
                    _appendText(sMsg, TextLogger);
                } catch (Exception e) {
                    _appendText(e);
                }
            }
        });
        workThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                _appendText("Thread UncaughtException:", TextHighWarning);
                _appendText(e);
            }
        });
        workThread.start();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
        onItemClick(position);
    }

    @Override
    public void onItemClick(final String str, final int position) {
        onItemClick(position);
    }

    public void Test() {
        for(int i = 0;i < 5; ++i) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            _appendText("i=" + i, TextMessage);
        }
    }
}
